function Models(){

	this.models = [];
	this.vertices = null;
	
	this.buffer = []; //holds all models for final stage of animation
	
	this.setVertices = function(vertices){
		this.vertices = vertices;
	};
	
	this.add = function(obj){
		var lastIndex = this.models.push(obj)-1;
		this.models[lastIndex].id = lastIndex;
		return lastIndex;
	};
	
	this.total = function(){
		return this.models.length;
	};
	
	this.get = function(index){
		return this.models[index];
	};
	
	
	this.updateById = function(id, param, value){
		for(var i=0; i < this.models.length; i++){
			if(this.models[i].id == id){
				this.models[i][param] = value;
				this.updateVertices();
				break;
			}
		}
	};
	

	this.updateByGroup = function(ax, ax_val, fname, angle){
		for(var i=0; i < this.models.length; i++){
			//find selected level (only selected group)
			if(this.models[i].initialCenter[ax] == ax_val){
				var newCoordiants = [];
				var oldCoordinats = this.models[i].coordinats;
				for(var k=0; k < oldCoordinats.length; k++){
					var transition3Dpoint = null;
					var transition3Dpoint = new Point3D( 
							oldCoordinats[k][0], 
							oldCoordinats[k][1], 
							oldCoordinats[k][2] 
							);
					transition3Dpoint = transition3Dpoint[fname](angle);
					if(angle == 90 || angle == -90){
						transition3Dpoint.x = Math.round(transition3Dpoint.x);
						transition3Dpoint.y = Math.round(transition3Dpoint.y); 
						transition3Dpoint.z = Math.round(transition3Dpoint.z);
					}
                    newCoordiants[k] = [transition3Dpoint.x, transition3Dpoint.y, transition3Dpoint.z];
				}
				this.models[i].grouped = true;
				this.models[i].coordinats = newCoordiants;
				
				//update initial center (cube center)
				var newCoordiants = [];
				var oldCoordinats = this.models[i].initialCenter;
				var transition3Dpoint = null;
				var transition3Dpoint = new Point3D( 
							oldCoordinats[0], 
							oldCoordinats[1], 
							oldCoordinats[2] 
				);
				transition3Dpoint = transition3Dpoint[fname](angle);
				if(angle == 90 || angle == -90){
					transition3Dpoint.x = Math.round(transition3Dpoint.x);
					transition3Dpoint.y = Math.round(transition3Dpoint.y); 
					transition3Dpoint.z = Math.round(transition3Dpoint.z);
				}
                newCoordiants = [transition3Dpoint.x, transition3Dpoint.y, transition3Dpoint.z];
				this.models[i].initialCenter = newCoordiants;
			}
		}
		this.updateVertices();
	};
	
	
	this.saveToBuffer = function(){
		this.buffer = [];
		for(var m=0; m<this.models.length; m++){
			var b = new Shape;
			for( var property in this.models[m] ){
				try{
					
					b[property] = this.models[m][property];
				}
				catch( warning ){console.log(warning);} //TODO: remove
			}
			this.buffer.push(b);
		}
	};
	
	this.loadBuffer = function(){
		this.models = [];
		for(var b=0; b<this.buffer.length; b++){
			var m = new Shape;
			for( var property in this.buffer[b] ){
				try{
					
					m[property] = this.buffer[b][property];
				}
				catch( warning ){console.log(warning);} //TODO: remove
			}
			this.models.push(m);
		}
		//this.models = this.buffer;
	};
	
	this.updateVertices = function(){
		this.vertices.reset();
		for( var i = 0; i < this.models.length; i++){
			this.vertices.loadModel(this.models[i]);
		}
	};
	
	this.sortModels = function(){
		this.models = remove_empty_models(this.models);
	};
	
	//private method
	function remove_empty_models(arr){
		var result_array = [];
		if(arr.length > 0){
			for(var i=0; i<arr.length; i++){
				if(typeof(arr[i]) == 'object')
				result_array.push(arr[i]);
			}
		}
		return result_array;
	}
}


	
